package cn.geckos.fml
{
	import flash.xml.*;
	import cn.geckos.fml.data.IData;
	import cn.geckos.fml.data.TextData;
	import cn.geckos.fml.data.LinkData;
	import cn.geckos.fml.data.PictureData;
	import cn.geckos.fml.data.StackData;
	
	public class FMLParser
	{
		private var xml:XML;
		
		public function FMLParser(xml:*)
		{
			if(xml is String)
				this.xml = new XML(xml);
			else if(xml is XML)
				this.xml = xml;
			else
				throw new Error("param error,only XML or String");	
		}
		
		public function deserialize():Array
		{
			return this.internalDeserialize(this.xml);
		}
		
		protected function internalDeserialize(xml:XML):Array
		{
			if(xml != null)
			{
				var collection:Array = new Array();
				var data:IData = null;
				var children:XMLList = xml.children();
				for each(var topNode:XML in children)
				{
					var name:String = topNode.name();
					switch(name)
					{
						case Type.TEXT:
							data = textType(topNode);
						break;
						case Type.LINK:
							data = linkType(topNode);
						break;
						case Type.PICTURE:
							data = pictureType(topNode);
						break;
						case Type.STACK:
							data = stackType(topNode);
						break;
						default:
							throw new Error("Parse FML syntax error");
						break;
					}
					collection.push(data);
					data = null;
				}
				
				return collection;
			}else
			{
				return null;
			}
		}
		
		private function textType(node:XML):IData
		{
			if(node.@id != undefined)
			{
				var text:TextData = new TextData();
				text.id = node.@id;
				if(node.@value != undefined)
				{
					text.text = node.@value;
				}else
				{
					text.text = node;
				}
				return text;
			}else
			{
				return null;
			}
		}
		
		private function linkType(node:XML):IData
		{
			if(node.@id != undefined)
			{
				var link:LinkData = new LinkData();
				link.id = node.@id;
				link.host = node.@host == undefined?"":node.@host;
				link.name = node.@name == undefined?"":node.@name;
				if(node.param != undefined)
				{
					var children:XMLList = node.children();
					for each(var cn:XML in children)
					{
						trace([cn.@name, cn.@value]);
						link.setParam(cn.@name, cn.@value);
					}
				}
				return link;
			}else
			{
				return null;
			}
		}
		
		private function pictureType(node:XML):IData
		{
			if(node.@id != undefined)
			{
				var pic:PictureData = new PictureData();
				pic.id = node.@id;
				if(node.@name != undefined)
				{
					pic.name = node.@name;
				}else
				{
					pic.name = node.name;
				}
				
				if(node.@link != undefined)
				{
					pic.link = node.@name;
				}else
				{
					pic.link = node.name;
				}
				return pic;
			}else
			{
				return null;
			}
		}
		
		private function stackType(node:XML):IData
		{
			if(node.@id != null)
			{
				var stack:StackData = new StackData();
				stack.id = node.@id;
				stack.stack = internalDeserialize(node);
				return stack;
			}else
			{
				return null;
			}
		}
	}
}